package org.openscheduler.modules.job;

import java.util.ArrayList;
import java.util.List;

import org.openscheduler.modules.scheduler.SchedulerService;
import org.quartz.Job;
import org.quartz.JobBuilder;
import org.quartz.JobDetail;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.Trigger;
import org.quartz.impl.matchers.GroupMatcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class JobService {
	
	@Autowired
	SchedulerService schedulerService;

	public List<Trigger> unscheduleJob(String schedName, JobKey jobKey) throws SchedulerException {
		List<Trigger> unremovedTriggers = new ArrayList<Trigger>();
		Scheduler scheduler = schedulerService.getScheduler(schedName);
		for (Trigger trigger : scheduler.getTriggersOfJob(jobKey)) {
			if (!scheduler.unscheduleJob(trigger.getKey())) {
				unremovedTriggers.add(trigger);
			}
		}
		return unremovedTriggers;
	}
	
	public JobDetail getJobDetail(String schedName, JobKey jobKey) throws SchedulerException {
		Scheduler scheduler = schedulerService.getScheduler(schedName);
		return scheduler.getJobDetail(jobKey);
	}
	
	public JobDetail getJobDetail(String schedName, String jobKeyName, String jobKeyGroup) throws SchedulerException {
		return getJobDetail(schedName, JobKey.jobKey(jobKeyName, jobKeyGroup));
	}
	
	public List<JobDetail> getAllJobDetails(Scheduler scheduler) throws SchedulerException {
		List<JobDetail> jobDetails = new ArrayList<JobDetail>();
		for (String jobGroupName : scheduler.getJobGroupNames()) {
			for (JobKey jobKey : scheduler.getJobKeys(GroupMatcher.jobGroupEquals(jobGroupName))) {
				JobDetail jobDetail = scheduler.getJobDetail(jobKey);
				jobDetails.add(jobDetail);
			}
		}
		return jobDetails;
	}
	
	public List<JobDetail> getAllJobDetails(String schedName) throws SchedulerException {
		return getAllJobDetails(schedulerService.getScheduler(schedName));
	}
	
	public boolean checkExists(String schedName, JobKey jobKey) throws SchedulerException {
		Scheduler scheduler = schedulerService.getScheduler(schedName);
		return scheduler.checkExists(jobKey);
	}

	public boolean checkExists(String schedName, String jobKeyName, String jobKeyGroup) throws SchedulerException {
		return checkExists(schedName, JobKey.jobKey(jobKeyName, jobKeyGroup));
	}
	
	@SuppressWarnings("unchecked")
	public JobDetail addJob(String schedName, JobTemplate beJob) throws SchedulerException, ClassNotFoundException {
		Scheduler scheduler = schedulerService.getScheduler(schedName);
		
		Class <? extends Job> jobClazz = (Class<? extends Job>) Class.forName(beJob.getClassName());
		JobBuilder jobBuilder = JobBuilder.newJob().ofType(jobClazz).withIdentity(beJob.getJobkey());
		if (beJob.getJobShouldRecover() != null) {
			jobBuilder.requestRecovery(beJob.getJobShouldRecover());
		}
		if (beJob.getJobDurability() != null) {
			jobBuilder.storeDurably(beJob.getJobDurability());
		}
		if (beJob.getJobDescription() != null) {
			jobBuilder.withDescription(beJob.getJobDescription());
		}
		if (beJob.getNewJobDataMap() != null) {
			jobBuilder.usingJobData(beJob.getNewJobDataMap());
		}
		JobDetail jobDetail = jobBuilder.build();
		
		scheduler.addJob(jobDetail, beJob.getReplace());
		
		return jobDetail;
	}
	
}
